// 访问器属性装饰器
// 参数一：类的原型(对象类型)
// 参数二：字符串，表示访问器属性名
// 参数三：属性描述对象，其实就是js的Object.defineProperty()中的属性描述对象{set:Function,get:Function, enumerable:xxx, configurable:xxx}


// function d(str: string) { 
//   return function (target: any, key: string, descriptor: PropertyDescriptor) {
//     const temp = descriptor.set!;
//     descriptor.set = function (...args:any[]) {
//       console.log("前置---", str)
//       temp.call(this, args);
//       console.log("后置---", str)
//     }
//   }
// }

//  descriptor也可以使用带泛型参数的类型TypedPropertyDescriptor<T>
/* function d(str: string) { 
  return function <T>(target: any, key: string, descriptor: TypedPropertyDescriptor<T>) {
    const temp = descriptor.set!;
    descriptor.set = function (value: T) {
      console.log("前置---", str)
      temp.call(this, value);
      console.log("后置---", str)
    }
  }
}

class User{
  public id: number;
  public name: string;
  private _age: number;

  // @d()
  // method1(){}

  @d("hello")
  set age(v: number) {
    console.log("set age---" + v)
    this._age = v;
  }

  get age() { 
    return this._age
  }
}
const u = new User();
u.age = 10; */

// 方法参数装饰器
// 参数一：如果是静态方法，为类本身，如果是实例属性，为类原型
// 参数二：字符串，表示方法名
// 参数三：数字，表示参数顺序

function paramDecorator(propertyName: string) {
  return function(target: any, key: string, index: number) {
    // console.log(target, key, index);
    !target.__params && (target.__params = {});
    target.__params[index] = propertyName;
  }
}


class A{
  method1(@paramDecorator("id") id: number, @paramDecorator("name") name: string) {
    console.log("---", id,name)
  }
  static method2(@paramDecorator("id") id: number, @paramDecorator("name") name: string) {
    console.log("---", id,name)
  }
}

const objA = new A();
objA.method1(1, "jack");

console.log(A.prototype);
console.log(A);
